/**
 * Created by meiguizhinian on 2018/7/17
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//单例/全静态/枚举
ivy.TeachDataManager = {
	getInstance: function () {
		return this;
	},

	//通过导出文件初始化教学数据
	initWithFile : function(filePath) {
		let is = new ivy.InputStream(filePath);
		if (is.isEmpty()) {
			cc.log("LoadFile :%s Failed!", filePath);
			return;
		}
		let sourceTeachTypeCount = is.readJInt16();
		for (let i = 0; i < sourceTeachTypeCount; ++i) {
			let typeName = is.readStringUTF8();
			let elementCount = is.readJInt16();
			let sTeachType = new ivy.SourceTeachType(typeName);
			for (let j = 0; j < elementCount; ++j) {
				let elementType = is.readJInt16();
				sTeachType.getElementTypeVec().push(elementType);
			}
			this.sourceTeachDataTypeVec_.push(sTeachType);
		}

		let teachDataFindIntMap = {};//std::map<int32_t, int32_t>
		let teachDataFindStringMap = {};//std::map<std::string, int32_t>
		let teachDataFindFloatMap = new LLDictionary();//std::map<float, int32_t >
		let teachDataFindVec2Map = new LLDictionary(cc.pointEqualToPoint);//std::map<cocos2d::Vec2, int32_t , compareVec2<cocos2d::Vec2>>
		let teachDataFindRectMap = new LLDictionary(cc.rectEqualToRect);//std::map<cocos2d::Rect, int32_t , compareRect<cocos2d::Rect>>
		let teachDataFindAniMap = new LLDictionary(cc.pointEqualToPoint);//std::map<cocos2d::Vec2, int32_t, compareVec2<cocos2d::Vec2>>

		let allTeachCount = is.readJInt16();
		for (let i = 0; i < allTeachCount; ++i) {
			let teachDataVec = [];//std::vector<TeachData>
			let childTeachDataCount = is.readJInt16();
			for (let j = 0; j < childTeachDataCount; ++j) {
				let typeIndex = is.readJInt16();
				let elementCount = is.readJInt16();
				cc.assert(typeIndex >= 0 && typeIndex < this.sourceTeachDataTypeVec_.length);
				cc.assert(this.sourceTeachDataTypeVec_[typeIndex].size() === elementCount);
				let sourceTeach = this.sourceTeachDataTypeVec_[typeIndex];
				let data = new ivy.TeachData();
				data.sourceTeachTypeInex_ = typeIndex;
				for (let k = 0; k < elementCount; ++k) {
					switch (sourceTeach.get(k)) {
						case ivy.SourceTeachType.BaseElementType.eInt: {
							let v = is.readJInt32();
							if (!teachDataFindIntMap[v]) {
								let size = Object.size(this.teachDataIntMap_);
								teachDataFindIntMap[v] = size;
								this.teachDataIntMap_[size] = v;
							}
							data.propertyFindIndexVec_[k] = teachDataFindIntMap[v];
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eString: {
							let v = is.readStringUTF8();
							if (teachDataFindStringMap[v]) {
								let size = Object.size(this.teachDataStringMap_);
								teachDataFindStringMap[v] = size;
								this.teachDataStringMap_[size] = v;
							}
							data.propertyFindIndexVec_[k] = teachDataFindStringMap[v];
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eRect: {
							let v1 = is.readJInt32();
							let v2 = is.readJInt32();
							let v3 = is.readJInt32();
							let v4 = is.readJInt32();
							let v = cc.rect(v1,v2,v3,v4);
							if (teachDataFindRectMap.has(v)) {
								data.propertyFindIndexVec_[k] = teachDataFindRectMap.get(v);
							} else {
								let size = Object.size(this.teachDataRectMap_);

								teachDataFindRectMap.set(v, size);
								data.propertyFindIndexVec_[k] = size;
								this.teachDataRectMap_[size] = v;
							}
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eFloat: {
							let v = is.readJInt32() / 100.0;
							if (teachDataFindFloatMap.has(v) ) {
								data.propertyFindIndexVec_[k] = teachDataFindFloatMap.get(v);
							} else {
								let size = Object.size(this.teachDataFloatMap_);

								teachDataFindFloatMap.set(v, size);
								data.propertyFindIndexVec_[k] = size;
								this.teachDataFloatMap_[size] = v;
							}
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eAni: {
							let v1 = is.readJInt16();
							let v2 = is.readJInt16();
							let v = cc.p(v1, v2);
							if (teachDataFindAniMap.has(v)) {
								data.propertyFindIndexVec_[k] = teachDataFindAniMap.get(v);
							} else {
								let size = Object.size(this.teachDataAniMap_);

								teachDataFindAniMap.set(v, size);
								data.propertyFindIndexVec_[k] = size;
								this.teachDataAniMap_[size] = [v1, v2];
							}
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eVec2F: {
							let v1 = is.readJInt32() / 100.0;
							let v2 = is.readJInt32() / 100.0;
							let vec = cc.p(v1, v2);
							if (teachDataFindVec2Map.has(vec)) {
								data.propertyFindIndexVec_[k] = teachDataFindVec2Map.get(vec);
							} else {
								let size = Object.size(this.teachDataVec2Map_);

								teachDataFindVec2Map.set(vec, size);
								data.propertyFindIndexVec_[k] = size;
								this.teachDataVec2Map_[size] = vec;
							}
							break;
						}
						case ivy.SourceTeachType.BaseElementType.eList:
						case ivy.SourceTeachType.BaseElementType.eAction: {
							let v = is.readJInt16();
							if (teachDataFindIntMap[v]) {
								data.propertyFindIndexVec_[k] = teachDataFindIntMap[v];
							} else {
								let size = Object.size(this.teachDataIntMap_);

								teachDataFindIntMap[v] = size;
								data.propertyFindIndexVec_[k] = size;
								this.teachDataIntMap_[size] = v;
							}
							break;
						}
						default:
							break;
					}
				}
				teachDataVec.push(data);
			}
			this.teachDataVec_.push(teachDataVec);
		}
	},
	//获取总教学数据数量
	getTeachDataCount : function() {
		return this.teachDataVec_.length;
	},
	//获取指定教学内容数据数量
	getTeachDataCountByIndex : function(mainIndex) {
		if (this.teachDataVec_.length > mainIndex) {
			return this.teachDataVec_[mainIndex].length;
		}
		return -1;
	},
	getTeachDataSourceTypeByIndex : function(mainIndex, childIndex) {
		if (this.teachDataVec_.length > mainIndex && this.teachDataVec_[mainIndex].length>childIndex) {
			return this.teachDataVec_[mainIndex][childIndex].sourceTeachTypeInex_;
		}
		return -1;
	},
	getTeachDataByIndex : function(mainIndex,childIndex) {
		if (this.teachDataVec_.length > mainIndex && this.teachDataVec_[mainIndex].length > childIndex) {
			return this.teachDataVec_[mainIndex][childIndex];
		}
		return null;
	},
	//获取数据接口
	getTeachIntDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataIntMap_[findIndex];
		}
		return 0;
	},
	getTeachStringDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataStringMap_[findIndex];
		}
		return "";
	},
	getTeachFloatDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataFloatMap_[findIndex];
		}
		return 0.0;
	},
	getTeachRectDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataRectMap_[findIndex];
		}
		return cc.rect(0,0,0,0);
	},
	getTeachVec2DataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataVec2Map_[findIndex];
		}
		return cc.p(0,0);
	},
	getTeachListDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataIntMap_[findIndex];
		}
		return -1;
	},
	getTeachActionDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataIntMap_[findIndex];
		}
		return -1;
	},
	getTeachAniDataBy : function(mainIndex, childIndex, propertyIndex) {
		if (this.checkIndexVaild(mainIndex, childIndex, propertyIndex)) {
			let findIndex = this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_[propertyIndex];
			return this.teachDataAniMap_[findIndex];
		}
		return [-1,-1];
	},
	//////////////////////////////////////////////////////////////////////////
	//批量获取数据接口
	// template<typename... Args>
	// void getTeachData(int32_t mainIndex, int32_t childIndex, Args&&... args) const
	// 	{
	// 		getTeachDataImpl(mainIndex,childIndex,std::forward<Args&&>(args)...);
	// }
	// private:
	// 	template<typename Value,typename... Args>
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex,int32_t propertyIndex, Value& val, Args&&... args) const
	// 	{
	// 		getTeachDataImpl(mainIndex,childIndex, propertyIndex,val);
	// getTeachData(mainIndex,childIndex,std::forward<Args&&>(args)...);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, std::string& val) const
	// 	{
	// 		val = getTeachStringDataBy(mainIndex,childIndex,propertyIndex);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, cocos2d::Rect& val) const
	// 	{
	// 		val = getTeachRectDataBy(mainIndex, childIndex, propertyIndex);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, cocos2d::Vec2& val) const
	// 	{
	// 		val = getTeachVec2DataBy(mainIndex, childIndex, propertyIndex);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, std::vector<int32_t>& val) const
	// 	{
	// 		val = getTeachAniDataBy(mainIndex, childIndex, propertyIndex);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, float& val) const
	// 	{
	// 		val = getTeachFloatDataBy(mainIndex, childIndex, propertyIndex);
	// }
	// void getTeachDataImpl(int32_t mainIndex, int32_t childIndex, int32_t propertyIndex, int32_t& val) const
	// 	{
	// 		val = getTeachIntDataBy(mainIndex, childIndex, propertyIndex);
	// }
	checkIndexVaild : function(mainIndex, childIndex, propertyIndex) {
		return mainIndex >= 0 && mainIndex < this.teachDataVec_.length &&
			childIndex>=0 && childIndex<this.teachDataVec_[mainIndex].length &&
			propertyIndex>=0 && propertyIndex<this.teachDataVec_[mainIndex][childIndex].propertyFindIndexVec_.length;
	},
	//源内容数据容器
	sourceTeachDataTypeVec_ : [],//std::vector<SourceTeachType>
	//数据映射容器
	teachDataVec_ : [],//std::vector<std::vector<TeachData>>
	//////////////////////////////////////////////////////////////////////////
	//实际数据存储区
	teachDataIntMap_ : {},//std::unordered_map<int32_t, int32_t>
	teachDataStringMap_ : {},//std::unordered_map<int32_t, std::string>
	teachDataFloatMap_ : {},//std::unordered_map<int32_t, float>
	teachDataVec2Map_ : {},//std::unordered_map<int32_t, cocos2d::Vec2>
	teachDataRectMap_ : {},//std::unordered_map<int32_t, cocos2d::Rect>
	teachDataAniMap_ : {},//std::unordered_map<int32_t, std::vector<int32_t>>
};

